#ifndef _COMPLEX_

#define _COMPLEX_

#include <math.h>

//include <complex>

const double Pi = 3.1415926535897932384626433;

class complex
	{
public:
	double re, im;

public:
	complex(const complex &x) { re = x.re; im = x.im; } 
	complex(const double& R = 0, const double& I = 0) { re = R; im = I; } 
	complex& operator=(const double& x)
		{re = x; im = 0; return (*this); }
	complex& trig(const double abs, const double arg)
		{re = abs * cos(arg); im = abs * sin(arg); return (*this); } 

	double abs() { return hypot(re, im); }
	double arg() { return atan2(im, re); }

    complex& operator -(const complex& a)
		{complex r(-a.re, -a.im); return r; }

	friend complex operator + (complex& a, complex& b)
		{ complex r(a.re + b.re, a.im + b.im); return r; }
	friend complex operator + (complex& a, const double b) 
		{ complex r(a.re + b, a.im); return r; }
	friend complex operator + (const double a, complex &b) 
		{ complex r(a + b.re, b.im); return r; }
	friend complex operator - (complex& a, complex &b)
		{ complex r(a.re - b.re, a.im - b.im); return r; }
	friend complex operator - (complex& a, const double b) 
		{ complex r(a.re - b, a.im); return r; }
	friend complex operator - (const double a, complex &b) 
		{ complex r(a - b.re, - b.im); return r; }
	friend complex operator * (complex& a, complex &b) 
		{ complex r(a.re * b.re - a.im * b.im, a.re * b.im + a.im * b.re); return r; }
	friend complex operator * (complex& a, const double b) 
		{ complex r(a.re * b, a.im * b); return r; }
	friend complex operator * (const double a, complex &b) 
		{ complex r(a * b.re, a * b.im); return r; }
	friend complex operator / (complex& a, const double b) 
		{ complex r(a.re / b, a.im / b); return r; }
	// die anderen / operatoren fehlen noch...

	complex& operator+=(const double x)
		{re += x; return (*this); } 
	complex& operator-=(const double x)
		{re -= x; return (*this); }
	complex& operator*=(const double x)
		{re *= x; im *= x; return (*this); }
	complex& operator/=(const double x)
		{re /= x; im /= x; return (*this); }

	complex& operator+=(const complex& x)
		{re += x.re; im += x.im; return (*this); } 
	complex& operator-=(const complex& x)
		{re -= x.re; im -= x.im; return (*this); }
	complex& operator*=(const complex& x)
		{double realt = re; 
	     re = re * x.re - im * x.im; 
		 im = im * x.re + realt * x.im;
		 return (*this); }


/*
	static double _Cosh(double x, double _Y)
		{return (::_Cosh((double)x, (double)_Y)); }
	static short _Exp(double *_P, double _Y, short _E)
		{double _W = (double)*_P;
		short _Ans = ::_Exp(&_W, (double)_Y, _E);
		*_P = (double)_W;
		return (_Ans); }
	static double _Infv(double)
		{return (_Inf._D); }
	static bool _Isinf(double x)
		{double _W = (double)x;
		return (_Dtest(&_W) == _INFCODE); }
	static bool _Isnan(double x)
		{double _W = (double)x;
		return (_Dtest(&_W) == _NANCODE); }
	static double _Nanv(double)
		{return (_Nan._D); }
	static double _Sinh(double x, double _Y)
		{return (::_Sinh((double)x, (double)_Y)); }
	static double atan2(double _Y, double x)
		{return (::atan2((double)_Y, (double)x)); }
	static double cos(double x)
		{return (::cos((double)x)); }
	static double exp(double x)
		{return (::exp((double)x)); }
	static double ldexp(double _R, int _E)
		{return (::ldexp((double)_R, _E)); }
	static double log(double x)
		{return (::log((double)x)); }
	static double pow(double x, double _Y)
		{return (::pow((double)x, (double)_Y)); }
	static double sin(double x)
		{return (::sin((double)x)); }
	static double sqrt(double x)
		{return (::sqrt((double)x)); }
*/

	};


#endif //_COMPLEX_